/*
 * Author: Kevin Ouwens; Gino Biervliet(Some changes); Roy Stegers(Some changes)
 *
 * newDownload function
 *
 * This is a rewrite of the old download.c for CHP.
 *
 * this module handles the download part of the CHP
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <semaphore.h>
#include "hfile.h"

/*
 * newdownload is a remake of download.c and that is the reason why it's called newdownload.
 * newdownload needs an int with the client fd ( descClient) and a clientInfo Struct Array (client[])
 * 
 */
int newdownload(int descClient, clientInfo client[])
{
    client[descClient].amountSent = 0, client[descClient].amountRead = 0, client[descClient].totalSent = 0;// long unisgned variables for counting the amount of data read/written.

    bzero(client[descClient].tempBuffer, CHUNKSIZE);//bzero the tempbuffer to make shure that there is no extra data in buffer
    printf("entered Downloadmmap \n");//Debug

    //post semaphoreEmpty to let FSP know that the mmf is empty
    if(sem_post(client[descClient].semaphoreEmpty) < 0)
    {
        perror("download semEmpty\n");
    }

    printf("posted empty\n");//Debug
    printf("waiting for semaphorefull...\n");//Debug

    //Wait for full mmf
    if(sem_wait(client[descClient].semaphoreFull) < 0)
    {
        perror("download semFull\n");
    }

    //send next bit of data to the client
    //do while construction to check condition at end of loop
    do
    {
        lseek(client[descClient].iMapFd, 0, SEEK_SET);//Reposition offset of mmf to 0 (begin of file)
        bzero(client[descClient].tempBuffer, CHUNKSIZE);//Bzero again to make sure there is no extra data.

        //if statement to read the mmf and write it to the tempBuffer with the strlen of the mmf
        if((client[descClient].amountRead = read(client[descClient].iMapFd, client[descClient].tempBuffer, strlen(client[descClient].cMapFile))) > 0)
        {
            printf("amountRead = %lu\n", client[descClient].amountRead);//Debug

            bzero(client[descClient].cMapFile, client[descClient].amountRead);//Bzero the mmf to avoid extra data

            printf("mmap is :%s\n", client[descClient].cMapFile);//Debug

            //lseek(client[descClient].iMapFd, CHUNKSIZE, SEEK_SET);

            printf("in download while\n");//Debug
            
            //send data in tempBuffer to client
            if((client[descClient].amountSent = send(descClient, client[descClient].tempBuffer, client[descClient].amountRead, 0))!=client[descClient].amountRead)
            {
                perror("incorrect amount of bytes!\n");
            }
            
            printf("sent: %s\n", client[descClient].tempBuffer);//Debug
            printf("amountSent = %lu\n", client[descClient].amountSent);//Debug

            client[descClient].totalSent += client[descClient].amountSent;//total plus amount send this loop

            printf("totalSent = %lu\n", client[descClient].totalSent);//Debug
            //Post empty to let the FSP know he can writes again
            if(sem_post(client[descClient].semaphoreEmpty) < 0)
            {
                perror("download semEmpty\n");
            }

            printf("posted semEmpty\n");//Debug

            printf("waiting for semaphorefull...\n");//Debug

            //Wait for FSP before start loop again
            if(sem_wait(client[descClient].semaphoreFull) < 0)
            {
                perror("download semFull\n");
            }
        }
        else if(client[descClient].amountRead < 0)//error handling for read above
        {
                perror("amountRead read\n");
        }
    }
    while(strlen(client[descClient].tempBuffer) == CHUNKSIZE);//check if tempbuff equals CHUNKSIZE before going trough loop again

    //End semaphore to reset everything.
    if(sem_post(client[descClient].semaphoreEmpty) < 0)
    {
        perror("download semEmpty\n");
    }
    printf("posted semEmpty\n");//Debug
    printf("exit download\n");//Debug
    return 0;
}